001    /* EVolve - an Extensible Software Visualization Framework
002     * Copyright (C) 2001-2002 Qin Wang
003     *
004     * This library is free software; you can redistribute it and/or
005     * modify it under the terms of the GNU Library General Public
006     * License as published by the Free Software Foundation; either
007     * version 2 of the License, or (at your option) any later version.
008     *
009     * This library is distributed in the hope that it will be useful,
010     * but WITHOUT ANY WARRANTY; without even the implied warranty of
011     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
012     * Library General Public License for more details.
013     *
014     * You should have received a copy of the GNU Library General Public
015     * License along with this library; if not, write to the
016     * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
017     * Boston, MA 02111-1307, USA.
018     */
019    
020    /*
021     * EVolve is distributed at http://www.sable.mcgill.ca/EVolve/
022     */
023    
024    package EVolve;
025    
026    import EVolve.data.*;
027    import EVolve.exceptions.*;
028    import EVolve.visualization.Visualization;
029    import java.awt.*;
030    import java.awt.event.*;
031    import java.util.*;
032    import java.io.*;
033    import javax.swing.*;
034    
035    public class Filter {
036        private ArrayList selection;
037        private ArrayList field;
038    
039        private final JDialog dialog;
040        private JDialog timeFrameChangeDialog;
041        private JSplitPane splitMain, splitLeft, splitLeftLower;
042        private JList listSelection, listField, listEntity;
043        private DefaultListModel modelSelection, modelField, modelEntity;
044        private JTextArea timeframeArea;
045        private JTextField textStartTime, textEndTime;
046    
047        private JPopupMenu popup;
048        private JMenuItem itemRename, itemCloneSelection, itemChangeTimeFrame;
049        private JMenuItem itemRemoveItems, itemKeepItems;
050        private int activateFieldIndex;
051    
052        public Filter() {
053            selection = new ArrayList();
054            field = new ArrayList();
055    
056            dialog = new JDialog(Scene.getFrame(), "Filter", false);
057    
058            final CardLayout cardButton = new CardLayout();
059            final JPanel panelButton = new JPanel(cardButton);
060            dialog.getContentPane().add(panelButton, BorderLayout.SOUTH);
061    
062            // selection
063            modelSelection = new DefaultListModel();
064            listSelection = new JList(modelSelection);
065            listSelection.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
066            listSelection.addMouseListener(new MouseAdapter() {
067                public void mousePressed(MouseEvent e) {
068                    updateSelection();
069                    cardButton.show(panelButton, "Selection");
070                }
071            });
072    
073            JScrollPane scrollSelection = new JScrollPane(listSelection, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
074            scrollSelection.setBackground(Color.white);
075            scrollSelection.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Selections"));
076    
077            JPanel panelSelection = new JPanel(new FlowLayout());
078            panelButton.add(panelSelection, "Selection");
079    
080            JButton buttonDeselect = new JButton("Deselect");
081            buttonDeselect.addActionListener(new ActionListener() {
082                public void actionPerformed(ActionEvent e) {
083                    listSelection.clearSelection();
084                }
085            });
086            panelSelection.add(buttonDeselect);
087    
088            JButton buttonColor = new JButton("Coloring");
089            buttonColor.addActionListener(new ActionListener() {
090                public void actionPerformed(ActionEvent e) {
091                    color();
092                }
093            });
094            panelSelection.add(buttonColor);
095    
096            JButton buttonFilter = new JButton("Decoloring");
097            buttonFilter.addActionListener(new ActionListener() {
098                public void actionPerformed(ActionEvent e) {
099                    filter();
100                }
101            });
102            panelSelection.add(buttonFilter);
103    
104            JButton buttonRemove = new JButton("Remove");
105            buttonRemove.addActionListener(new ActionListener() {
106                public void actionPerformed(ActionEvent e) {
107                    remove();
108                }
109            });
110            panelSelection.add(buttonRemove);
111    
112            JButton buttonSelectionClose = new JButton("Close");
113            buttonSelectionClose.addActionListener(new ActionListener() {
114                public void actionPerformed(ActionEvent e) {
115                    dialog.setVisible(false);
116                }
117            });
118            panelSelection.add(buttonSelectionClose);
119    
120            // field
121            modelField = new DefaultListModel();
122            listField = new JList(modelField);
123            listField.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
124            listField.addMouseListener(new MouseAdapter() {
125                public void mousePressed(MouseEvent e) {
126                    updateField();
127                    cardButton.show(panelButton, "Field");
128                }
129            });
130            listField.setEnabled(false);
131    
132            JScrollPane scrollField = new JScrollPane(listField, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
133            scrollField.setBackground(Color.white);
134            scrollField.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Fields"));
135    
136            JPanel panelField = new JPanel(new FlowLayout());
137            panelButton.add(panelField, "Field");
138    
139            JButton buttonSelectAll = new JButton("Select All");
140            buttonSelectAll.addActionListener(new ActionListener() {
141                public void actionPerformed(ActionEvent e) {
142                    selectAll();
143                }
144            });
145            panelField.add(buttonSelectAll);
146    
147            JButton buttonClearAll = new JButton("Clear All");
148            buttonClearAll.addActionListener(new ActionListener() {
149                public void actionPerformed(ActionEvent e) {
150                    clearAll();
151                }
152            });
153            panelField.add(buttonClearAll);
154    
155            JButton buttonFieldClose = new JButton("Close");
156            buttonFieldClose.addActionListener(new ActionListener() {
157                public void actionPerformed(ActionEvent e) {
158                    dialog.setVisible(false);
159                }
160            });
161            panelField.add(buttonFieldClose);
162    
163            // entity
164            modelEntity = new DefaultListModel();
165            listEntity = new JList(modelEntity);
166            listEntity.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
167            listEntity.addMouseListener(new MouseAdapter() {
168                public void mousePressed(MouseEvent e) {
169                    cardButton.show(panelButton, "Entity");
170                }
171            });
172    
173            JScrollPane scrollEntity = new JScrollPane(listEntity, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
174            scrollEntity.setBackground(Color.white);
175            scrollEntity.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Selected Entities"));
176    
177            timeframeArea = new JTextArea();
178            timeframeArea.setBackground(Color.white);
179            timeframeArea.append("   ");
180    
181            JScrollPane scrollTimeFrame = new JScrollPane(timeframeArea,ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
182            scrollTimeFrame.setBackground(Color.white);
183            scrollTimeFrame.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Selected Time Frame"));
184    
185            JPanel panelEntity = new JPanel(new FlowLayout());
186            panelButton.add(panelEntity, "Entity");
187    
188            JButton buttonRemoveSelected = new JButton("Remove Selected");
189            buttonRemoveSelected.addActionListener(new ActionListener() {
190                public void actionPerformed(ActionEvent e) {
191                    removeSelected();
192                }
193            });
194            panelEntity.add(buttonRemoveSelected);
195    
196            JButton buttonRemoveUnselected = new JButton("Remove Unselected");
197            buttonRemoveUnselected.addActionListener(new ActionListener() {
198                public void actionPerformed(ActionEvent e) {
199                    removeUnselected();
200                }
201            });
202            panelEntity.add(buttonRemoveUnselected);
203    
204            JButton buttonEntityClose = new JButton("Close");
205            buttonEntityClose.addActionListener(new ActionListener() {
206                public void actionPerformed(ActionEvent e) {
207    
208                    dialog.setVisible(false);
209                }
210            });
211            panelEntity.add(buttonEntityClose);
212    
213            splitLeftLower = new JSplitPane(JSplitPane.VERTICAL_SPLIT, scrollField, scrollTimeFrame);
214            splitLeftLower.setDividerSize(2);
215            splitLeft = new JSplitPane(JSplitPane.VERTICAL_SPLIT, scrollSelection, splitLeftLower);
216            splitLeft.setDividerSize(2);
217    
218            splitMain = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, splitLeft, scrollEntity);
219            splitMain.setDividerSize(2);
220            dialog.getContentPane().add(splitMain, BorderLayout.CENTER);
221    
222            createMenu();
223            addPopupTrigger(listSelection);
224        }
225    
226        public void load() {
227            dialog.pack();
228            Scene.getUIManager().showDialog(dialog, Toolkit.getDefaultToolkit().getScreenSize().width / 2, Toolkit.getDefaultToolkit().getScreenSize().height * 3 / 4);
229            splitMain.setDividerLocation(0.5);
230            splitLeft.setDividerLocation(0.5);
231            splitLeftLower.setDividerLocation(0.5);
232            updateSelection();
233        }
234    
235        public void addSelection(Selection selection) {
236            String newName = (String)JOptionPane.showInputDialog(Scene.getFrame(),
237                    "Selection Options:\n"+Scene.getUIManager().getSelectionOptions() + "\nName of the selection:",
238                    "Add Selection",
239                    JOptionPane.QUESTION_MESSAGE, null, null, selection.getName());
240            if (newName != null) {
241                selection.setName(newName);
242    
243                this.selection.add(selection);
244                update();
245    
246                listSelection.setSelectedIndex(this.selection.size() - 1);
247                updateSelection();
248    
249                if (!dialog.isVisible()) {
250                    load();
251                }
252            }
253        }
254    
255        private void update() {
256            modelSelection.removeAllElements();
257            for (int i = 0; i < selection.size(); i++) {
258                Selection s = (Selection)(selection.get(i));
259                if (s.getColor() == null) {
260                    modelSelection.addElement("* " + s.getName() + " (" + Scene.getDataManager().getElementDefinition()[((Selection)(selection.get(i))).getEntityType()].getName() + ")");
261                } else {
262                    modelSelection.addElement("<html><font color=#" + getColorHex(s.getColor()) + ">" + s.getName() + " (" + Scene.getDataManager().getElementDefinition()[((Selection)(selection.get(i))).getEntityType()].getName() + ")</font></html>");
263                }
264            }
265        }
266    
267        private void updateTimeFrameInfo() {
268            timeframeArea.replaceRange(null,0,timeframeArea.getText().length());
269            Selection selected = getActiveSelection();
270            if (selected != null) {
271                //String info = "Start Event no.(overall): " + selected.getStart() + "\n";
272                //info = info + "End Event no.(overall): " + selected.getEnd() + "\n";
273                String info = "";
274                if (selected.getStartTime() != -1) {
275                    info = info + "Start Time: " + selected.getStartTime() + "\n";
276                    info = info + "End Time: " + selected.getEndTime() + "\n";
277                } else {
278                    info = info + "Start Time: begin of the trace\n";
279                    info = info + "End Time: end of the trace\n";
280                }
281                timeframeArea.append(info);
282            }
283    
284        }
285    
286        private String getColorHex(Color color) {
287            String returnVal = Integer.toHexString(color.getBlue());
288            if (returnVal.length() < 2) {
289                returnVal = "0" + returnVal;
290            }
291            returnVal = Integer.toHexString(color.getGreen()) + returnVal;
292            if (returnVal.length() < 4) {
293                returnVal = "0" + returnVal;
294            }
295            returnVal = Integer.toHexString(color.getRed()) + returnVal;
296            if (returnVal.length() < 6) {
297                returnVal = "0" + returnVal;
298            }
299    
300            return returnVal;
301        }
302    
303        public void updateSelection() {
304            if (listSelection.getSelectedIndex() != -1) {
305                modelField.removeAllElements();
306                modelEntity.removeAllElements();
307    
308                Selection s = (Selection)(selection.get(listSelection.getSelectedIndex()));
309    
310                for (int i = 0; i < s.getSelected().length; i++) {
311                    modelEntity.addElement(s.getSelected()[i].getName());
312                }
313    
314                ArrayList vizType = Scene.getVisualizationManager().getVisualizationType();
315                field.clear();
316                ReferenceLink[] link = Scene.getDataManager().getReferenceLink();
317    
318                activateFieldIndex = -1;
319                Selection selection = getActiveSelection();
320                for (int i = 0; i < link.length; i++) {
321                    /*if ((vizType.indexOf("" + link[i].getSourceType() + "") != -1) && (link[i].getTargetType() == s.getEntityType())) {
322                        field.add(link[i]);
323                    }*/
324                    if (vizType.indexOf("" + link[i].getSourceType() + "") != -1) {
325                        if (Scene.getDataManager().getElementDefinition()[link[i].getSourceType()].getType()==selection.getSourceType()) {
326                            if (link[i].getTargetType() == s.getEntityType())
327                                activateFieldIndex = field.size();
328                            field.add(link[i]);
329                        }
330                    }
331                }
332    
333                for (int i = 0; i < field.size(); i++) {
334                    modelField.addElement(((ReferenceLink)(field.get(i))).getName() + " (" + Scene.getDataManager().getElementDefinition()[((ReferenceLink)(field.get(i))).getSourceType()].getName() + ")");
335                }
336    
337                /*ArrayList selected = new ArrayList();
338                for (int i = 0; i < s.getLink().length; i++) {
339                    if (field.indexOf(s.getLink()[i]) != -1) {
340                        selected.add(new Integer(field.indexOf(s.getLink()[i])));
341                    }
342                }
343                selected.add(new Integer(activateFieldIndex));
344    
345                int[] selectedLink = new int[selected.size()];
346                for (int i = 0; i < selectedLink.length; i++) {
347                    selectedLink[i] = ((Integer)(selected.get(i))).intValue();
348                }
349                listField.setSelectedIndices(selectedLink);*/
350                listField.setSelectedIndex(activateFieldIndex);
351    
352                updateTimeFrameInfo();
353                updateField();
354            }
355        }
356    
357        private void updateField() {
358            if (listSelection.getSelectedIndex() != -1) {
359                ReferenceLink[] newLink = new ReferenceLink[listField.getSelectedIndices().length];
360                for (int i = 0; i < newLink.length; i++) {
361                    newLink[i] = (ReferenceLink)(field.get(listField.getSelectedIndices()[i]));
362                }
363    
364                Selection s = (Selection)(selection.get(listSelection.getSelectedIndex()));
365                s.setLink(newLink);
366            }
367        }
368    
369        private void updateEntity() {
370            if (listSelection.getSelectedIndex() != -1) {
371                modelEntity.removeAllElements();
372    
373                Selection s = (Selection)(selection.get(listSelection.getSelectedIndex()));
374                for (int i = 0; i < s.getSelected().length; i++) {
375                    modelEntity.addElement(s.getSelected()[i].getName());
376                }
377            }
378        }
379    
380        private void color() {
381            if (listSelection.getSelectedIndex() != -1) {
382                Color newColor = JColorChooser.showDialog(Scene.getFrame(), "Choose a color", Color.black);
383                if (newColor != null) {
384                    int selected = listSelection.getSelectedIndex();
385                    ((Selection)(selection.get(selected))).setColor(newColor);
386                    update();
387    
388                    listSelection.setSelectedIndex(selected);
389                    updateSelection();
390                }
391            }
392        }
393    
394        private void filter() {
395            if (listSelection.getSelectedIndex() != -1) {
396                int selected = listSelection.getSelectedIndex();
397                ((Selection)(selection.get(selected))).setColor(null);
398                update();
399    
400                listSelection.setSelectedIndex(selected);
401                updateSelection();
402            }
403        }
404    
405        private void remove() {
406            if (listSelection.getSelectedIndex() != -1) {
407                selection.remove(listSelection.getSelectedIndex());
408                update();
409            }
410        }
411    
412        private void selectAll() {
413            /*if (listSelection.getSelectedIndex() != -1) {
414                int[] all = new int[modelField.size()];
415                for (int i = 0; i < all.length; i++) {
416                    all[i] = i;
417                }
418                listField.setSelectedIndices(all);
419                updateField();
420            }*/
421        }
422    
423        private void clearAll() {
424            if (listSelection.getSelectedIndex() != -1) {
425                listField.setSelectedIndices(new int[0]);
426                updateField();
427            }
428        }
429    
430        private void removeSelected() {
431            if (listSelection.getSelectedIndex() != -1) {
432                Selection s = (Selection)(selection.get(listSelection.getSelectedIndex()));
433                int[] index = listEntity.getSelectedIndices();
434                Entity[] newEntity = new Entity[s.getSelected().length - index.length];
435    
436                int j = 0;
437                int k = 0;
438                for (int i = 0; i < newEntity.length; i++) {
439                    while ((j < index.length) && (index[j] == k)) {
440                        j++;
441                        k++;
442                    }
443                    newEntity[i] = s.getSelected()[k];
444                    k++;
445                }
446                s.setSelected(newEntity);
447                updateEntity();
448            }
449        }
450    
451        private void removeUnselected() {
452            if (listSelection.getSelectedIndex() != -1) {
453                Selection s = (Selection)(selection.get(listSelection.getSelectedIndex()));
454                int[] index = listEntity.getSelectedIndices();
455                Entity[] newEntity = new Entity[index.length];
456    
457                for (int i = 0; i < newEntity.length; i++) {
458                    newEntity[i] = s.getSelected()[index[i]];
459                }
460                s.setSelected(newEntity);
461                updateEntity();
462            }
463        }
464    
465        public Selection[] getSelection() {
466            Selection[] returnVal = new Selection[selection.size()];
467            for (int i = 0; i < returnVal.length; i++) {
468                returnVal[i] = (Selection)(selection.get(i));
469            }
470    
471            return returnVal;
472        }
473    
474        public Selection getActiveSelection() {
475            int selectedIndex = listSelection.getSelectedIndex();
476    
477            if (selectedIndex == -1) return null;
478    
479            return (Selection)selection.get(selectedIndex);
480        }
481    
482        public void saveSelection() {
483            JFileChooser fc = new JFileChooser();
484            if (fc.showSaveDialog(Scene.getFrame()) == JFileChooser.APPROVE_OPTION) {
485                try {
486                    FileWriter file = new FileWriter(fc.getSelectedFile().getPath(),false);
487                    writeSelection(file,"Default");
488                } catch (IOException e) {}
489            }
490        }
491    
492        public void saveSelection(FileWriter file, String selectionName) {
493            try {
494                writeSelection(file,selectionName);
495            } catch (IOException e) {}
496        }
497    
498        public void loadSelection(RandomAccessFile file) throws EVolveException{
499            Selection newSelection = null;
500            int start, end, sourceType, entityType,startTime,endTime;
501            long selected[];
502            ArrayList IDs,timeMap;
503            String currentName, line;
504            StringTokenizer token;
505            Color color;
506    
507            this.selection.clear();
508    
509            try {
510                String version = file.readLine().trim();
511                if (!version.equals(Scene.VERSION)) throw (new WrongVersionException(version));
512    
513                String fileType = file.readLine(); //get file type
514                fileType = fileType.substring(fileType.indexOf(':')+1);
515                if (fileType.charAt(0) != 'S') throw new FileTypeMismatchException("Selection file", fileType+" file");
516    
517    
518                file.readLine();
519    
520                line = file.readLine().trim();
521                while (line!=null) {
522                    timeMap = null;
523                    currentName = line.trim(); //get selection name
524                    line = file.readLine().trim(); //get start position of x
525                    start = Integer.parseInt(line.substring(line.indexOf(':')+1));
526                    line = file.readLine().trim(); //get end position of x
527                    end = Integer.parseInt(line.substring(line.indexOf(':')+1));
528    
529                    line = file.readLine().trim(); //get start time of x
530                    startTime = Integer.parseInt(line.substring(line.indexOf(':')+1));
531                    line = file.readLine().trim(); //get start time of x
532                    endTime = Integer.parseInt(line.substring(line.indexOf(':')+1));
533    
534                    file.readLine(); //skip tag
535                    line = file.readLine().trim();
536                    token = new StringTokenizer(line,",");
537                    while (token.hasMoreTokens()) {
538                        if (timeMap == null) timeMap = new ArrayList();
539                        long[] value = new long[2];
540                        value[0] = Long.parseLong(token.nextToken());
541                        value[1] = Long.parseLong(token.nextToken());
542                    }
543    
544                    line = file.readLine().trim();//get source type
545                    sourceType = Integer.parseInt(line.substring(line.indexOf(':')+1));
546                    line = file.readLine().trim(); //get entity type
547                    entityType = Integer.parseInt(line.substring(line.indexOf(':')+1));
548                    line = file.readLine().trim(); //get color
549                    line = line.substring(line.indexOf(':')+1);
550                    color = null;
551                    if (line.charAt(0)!='n')
552                        color = new Color(Integer.parseInt(line));
553    
554                    file.readLine(); //skip tag
555                    line = file.readLine().trim(); // read entity ids
556                    token = new StringTokenizer(line,",");
557    
558                    IDs = new ArrayList();
559                    while (token.hasMoreTokens()) {
560                        IDs.add(token.nextToken());
561                    }
562                    selected = new long[IDs.size()];
563                    for (int k=0; k<selected.length; k++)
564                        selected[k] = Long.parseLong((String)IDs.get(k));
565    
566                    newSelection = new Selection(sourceType,entityType,selected,start,end,timeMap);
567                    newSelection.setName(currentName);
568                    newSelection.setColor(color);
569                    line = file.readLine();
570                    this.selection.add(newSelection);
571                    update();
572    
573                    listSelection.setSelectedIndex(this.selection.size() - 1);
574                    updateSelection();
575                }
576                Scene.getUIManager().enableSelectionMenu();
577                file.close();
578            } catch (IOException e) {
579                Scene.showErrorMessage("Error occurred when trying to save selections!");
580            }
581    
582        }
583    
584        private void writeSelection(FileWriter file, String selectionName) throws IOException {
585            Selection currentSelection;
586            String currentSelectionName;
587            long start, end, entityType;
588            Entity[] entities;
589            ArrayList timeMap;
590    
591            file.write(Scene.VERSION+"\n");
592            file.write("File Type:Selection\n");
593            file.write(selectionName+"\n");
594            for (int i=0; i<selection.size(); i++) {
595                timeMap = null;
596                currentSelection = (Selection)selection.get(i);
597                start = currentSelection.getStart();
598                end = currentSelection.getEnd();
599                entityType = currentSelection.getEntityType();
600                currentSelectionName = currentSelection.getName();
601                entities = currentSelection.getSelected();
602    
603                file.write(currentSelectionName+"\n");
604                file.write("Start:"+start+"\n");
605                file.write("End:"+end+"\n");
606                file.write("StartTime:"+currentSelection.getStartTime()+"\n");
607                file.write("EndTime:"+currentSelection.getEndTime()+"\n");
608    
609                file.write("Time map:\n");
610                timeMap = currentSelection.getTimeMap();
611                if (timeMap != null) {
612                    for (int j=0; j<timeMap.size(); j++) {
613                        long[] value = (long[])timeMap.get(j);
614                        file.write(value[0]+","+value[1]+",");
615                    }
616                }
617                file.write("\n");
618    
619                file.write("Source type:"+currentSelection.getSourceType()+"\n");
620                file.write("Entity type:"+entityType+"\n");
621                if (currentSelection.getColor() != null)
622                    file.write("Color:"+currentSelection.getColor().getRGB()+"\n");
623                else
624                    file.write("Color:null"+"\n");
625                file.write("Selected ID list:\n");
626                for (int j=0; j<entities.length; j++) {
627                    file.write(entities[j].getId()+",");
628                }
629                file.write("\n");
630            }
631            file.flush();
632            file.close();
633    
634        }
635    
636        public Selection getNewestSelection() {
637            return (Selection)selection.get(selection.size()-1);
638        }
639    
640        public void selectWithRegExp() {
641            int selectionNumber = selection.size();
642    
643            Visualization viz = Scene.getVisualizationManager().getActiveVisualization();
644    
645            if (viz == null) return;
646    
647            viz.makeSelection();
648    
649            if (selection.size() > selectionNumber) {
650                for (int i=selectionNumber; i<selection.size(); i++) {
651                    String patterns = JOptionPane.showInputDialog(Scene.getFrame(),
652                                      "Input pattern expression(s).\n(seperated with \";\")");
653                    if (patterns != null) {
654                        patterns = generateRegExp(patterns);
655                        Selection added = (Selection)selection.get(i);
656                        added.filterEntities(patterns,true);
657                    }
658                }
659                updateSelection();
660            }
661        }
662    
663        private String generateRegExp(String inputs) {
664            String returnVal = "";
665            StringTokenizer token = new StringTokenizer(inputs+";",";");
666            while (token.hasMoreTokens()) {
667                String input = token.nextToken();
668                for (int i=0; i<input.length(); i++) {
669                    char aChar = input.charAt(i);
670                    switch (aChar) {
671                        case '*':
672                            returnVal = returnVal + ".{1,}";
673                            break;
674                        case '.':
675                            returnVal += "/{1}";
676                            break;
677                        case '?':
678                            returnVal += '.';
679                            break;
680                        default:
681                            returnVal += aChar;
682                            break;
683                    }
684                }
685                returnVal += ';';
686            }
687            return returnVal;
688        }
689    
690        private void createMenu() {
691            popup = new JPopupMenu();
692    
693            itemRename = new JMenuItem("Rename Selection ...");
694            itemRename.setMnemonic(KeyEvent.VK_R);
695            itemRename.addActionListener(new ActionListener() {
696                public void actionPerformed(ActionEvent e) {
697                    Selection selected = getActiveSelection();
698                    if (selected != null) {
699                        String newName = JOptionPane.showInputDialog(selected.getName());
700                        selected.setName(newName);
701                        update();
702                    }
703                }
704            });
705            popup.add(itemRename);
706    
707            itemCloneSelection = new JMenuItem("Clone Current Selection");
708            itemCloneSelection.setMnemonic(KeyEvent.VK_C);
709            itemCloneSelection.addActionListener(new ActionListener() {
710                public void actionPerformed(ActionEvent e) {
711                    Selection selected = getActiveSelection();
712                    if (selected != null) {
713                        Selection newSelection = (Selection)selected.clone();
714                        addSelection(newSelection);
715                    }
716                }
717            });
718            popup.add(itemCloneSelection);
719    
720            itemChangeTimeFrame = new JMenuItem("Change Time Frame");
721            itemChangeTimeFrame.setMnemonic(KeyEvent.VK_C);
722            itemChangeTimeFrame.addActionListener(new ActionListener() {
723                public void actionPerformed(ActionEvent e) {
724                    Selection selected = getActiveSelection();
725                    if (selected != null) {
726                        createChangeTimeDialog(selected);
727                    }
728                }
729            });
730            popup.add(itemChangeTimeFrame);
731    
732            itemRemoveItems = new JMenuItem("Remove Entities ...");
733            itemRemoveItems.setMnemonic(KeyEvent.VK_R);
734            itemRemoveItems.addActionListener(new ActionListener() {
735                public void actionPerformed(ActionEvent e) {
736                    filterEntities(false);
737                }
738            });
739            popup.add(itemRemoveItems);
740    
741            itemKeepItems = new JMenuItem("Remove All Entities Except ...");
742            itemKeepItems.setMnemonic(KeyEvent.VK_E);
743            itemKeepItems.addActionListener(new ActionListener() {
744                public void actionPerformed(ActionEvent e) {
745                    filterEntities(true);
746                }
747            });
748            popup.add(itemKeepItems);
749        }
750    
751        private void addPopupTrigger(Component component) {
752    
753            component.addMouseListener(new MouseAdapter() {
754                public void mouseReleased(MouseEvent e) {
755                    if (e.isPopupTrigger()) {
756                        showPopup(e);
757                    }
758                }
759    
760                public void mousePressed(MouseEvent e) {
761                    if (e.isPopupTrigger()) {
762                        showPopup(e);
763                    }
764                }
765            });
766        }
767    
768        private void showPopup(MouseEvent e) {
769            int mouseX = e.getX();
770            int mouseY = e.getY();
771            Rectangle rect = e.getComponent().getBounds();
772            Rectangle rect2 = popup.getBounds();
773            int posX= mouseX, posY = mouseY;
774            if (mouseY+rect2.height > rect.height)
775                posY = posY - rect2.height;
776            if (mouseX+rect2.width>rect.width)
777                posX = posX - rect2.width;
778                popup.show(e.getComponent(), posX, posY);
779        }
780    
781        private void createChangeTimeDialog(Selection selected) {
782    
783            if (timeFrameChangeDialog == null) {
784                textStartTime = new JTextField(String.valueOf(selected.getStartTime()));
785                textEndTime = new JTextField(String.valueOf(selected.getEndTime()));
786                timeFrameChangeDialog = new JDialog(dialog,"Change Time Frame",true);
787    
788                Box boxMain = new Box(BoxLayout.Y_AXIS);
789                boxMain.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(),
790                        "Choose range"));
791                timeFrameChangeDialog.getContentPane().add(boxMain,BorderLayout.CENTER);
792    
793                boxMain.add(new JLabel("Start time:"));
794                boxMain.add(textStartTime);
795                boxMain.add(new JLabel("End time:"));
796                boxMain.add(textEndTime);
797    
798                timeFrameChangeDialog.getContentPane().add(boxMain, BorderLayout.CENTER);
799    
800                JPanel panelButton = new JPanel(new FlowLayout());
801                timeFrameChangeDialog.getContentPane().add(panelButton, BorderLayout.SOUTH);
802    
803                JButton buttonApply = new JButton("Ok");
804                buttonApply.addActionListener(new ActionListener() {
805                    public void actionPerformed(ActionEvent e) {
806                        Selection selected = getActiveSelection();
807                        if (selected != null) {
808                            try {
809                                long start = Long.parseLong(textStartTime.getText());
810                                long end = Long.parseLong(textEndTime.getText());
811                                selected.changeTimeFrame(start,end);
812                                updateTimeFrameInfo();
813                                timeFrameChangeDialog.setVisible(false);
814                            } catch (NumberFormatException e1) {
815                                Scene.showErrorMessage("Only numbers are allowed.");
816                            }
817                        }
818                    }
819                });
820                panelButton.add(buttonApply);
821    
822                JButton buttonCancel = new JButton("Cancel");
823                buttonCancel.addActionListener(new ActionListener() {
824                    public void actionPerformed(ActionEvent e) {
825                        timeFrameChangeDialog.setVisible(false);
826                    }
827                });
828                panelButton.add(buttonCancel);
829                timeFrameChangeDialog.pack();
830            } else {
831                textStartTime.setText(String.valueOf(selected.getStartTime()));
832                textEndTime.setText(String.valueOf(selected.getEndTime()));
833            }
834    
835            Scene.getUIManager().showDialog(timeFrameChangeDialog, timeFrameChangeDialog.getWidth(), timeFrameChangeDialog.getHeight());
836        }
837    
838        private void filterEntities(boolean keepMatched) {
839            int selected = listSelection.getSelectedIndex();
840            if (selected == -1) return;
841            String patterns = JOptionPane.showInputDialog(Scene.getFrame(),
842                              "Input pattern expression(s).\n(seperated with \";\")");
843            if (patterns != null) {
844                patterns = generateRegExp(patterns);
845                Selection tobeChanged = (Selection)selection.get(selected);
846                tobeChanged.filterEntities(patterns, keepMatched);
847            }
848            updateSelection();
849        }
850    
851    }